package it.infodea.tapestrydea.components.jcr;

import it.infodea.tapestrydea.services.jcr.JcrWorkspaceService;
import it.infodea.tapestrydea.services.jcr.nodes.wrappers.JcrFileNode;

import java.util.List;

import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.version.Version;

import org.apache.tapestry5.Asset;
import org.apache.tapestry5.ComponentEventCallback;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.annotations.IncludeStylesheet;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.internal.util.Holder;
import org.apache.tapestry5.ioc.annotations.Inject;

@IncludeStylesheet("FoldersNavigator.css")
public class VersionsNavigator {

	private static final String JCR_ROOT_VERSION_NAME = "jcr:rootVersion";
	public static final String SELECT_VERSION_EVENT = "selectVersion";
	public static final String RESTORE_VERSION_EVENT = "restoreVersion";
	private static final String INTERNAL_SELECT_EVENT_NAME = "versionNavigator_selectVersion";
	private static final String INTERNAL_RESTORE_EVENT_NAME = "versionNavigator_restoreVersion";

	@Inject
	@Path("classpath:/it/infodea/tapestrydea/components/jcr/restore.png")
	private Asset restoreImage;
	
	@Parameter(name="uuid", required=true)
	private String uuid;

	@Persist
	private JcrFileNode file;
	
	@SuppressWarnings("unused")
	@Property
	private int index;

	private List<Version> versionsList;
	
	private Version versionItem;

	@Inject
	private ComponentResources _resources;
	
	@Inject
	private JcrWorkspaceService service;
	
	@BeginRender
	void setup() throws RepositoryException{
		if(uuid != null){
			file = service.getFileByUUID(uuid);
			versionsList = file.getVersionHistory();
		}
	}
	
	@OnEvent(INTERNAL_SELECT_EVENT_NAME)
	Object selectVersion(int index) throws PathNotFoundException, RepositoryException{
		Version version = file.getVersionHistory().get(index);
		if(version != null){
			return triggerEvent(SELECT_VERSION_EVENT, file, version);
		}
		return null;
	}
	
	@OnEvent(INTERNAL_RESTORE_EVENT_NAME)
	Object restoreVersion(int index) throws PathNotFoundException, RepositoryException{
		Version version = file.getVersionHistory().get(index);
		if(version != null){
			return triggerEvent(RESTORE_VERSION_EVENT, file, version);
		}
		return null;
	}
	
	private Object triggerEvent(String eventName, JcrFileNode file, Version version){
		final Holder<Object> resultHolder = Holder.create();

		ComponentEventCallback<Object> handler = new ComponentEventCallback<Object>() {

			public boolean handleResult(Object result) {
				resultHolder.put(result.toString());
				return true;
			}
		};

		_resources.triggerEvent(eventName, new Object[] { file, version },
				handler);
		
		return resultHolder.get();
	}
	
	public JcrFileNode getFile() {
		return file;
	}

	public List<Version> getVersionsList() {
		return versionsList;
	}

	public Version getVersionItem() {
		return versionItem;
	}

	public void setVersionItem(Version versionItem) {
		this.versionItem = versionItem;
	}

	public Asset getRestoreImage() {
		return restoreImage;
	}

	public boolean isEditable() throws UnsupportedRepositoryOperationException, RepositoryException{
		return !isRootVersion(versionItem);
	}

	private boolean isRootVersion(Version versionItem) throws RepositoryException {
		return JCR_ROOT_VERSION_NAME.equals(versionItem.getName());
	}
}
